package redis_db

import (
	"context"
	"encoding/json"
	"github.com/redis/go-redis/v9"
	"time"
)

// Exist
// Determine if the key is in Redis
func (r *RdbConfig) Exist(key string) bool {
	value, err := r.rDB.Exists(context.Background(), key).Result()
	if err != nil {
		return false
	}
	return value > 0
}

// Delete
// delete Key-Value Pairs from Redis
func (r *RdbConfig) Delete(key string) (bool, error) {
	value, err := r.rDB.Del(context.Background(), key).Result()
	return value > 0, err
}

// Set
// Manipulate String type, write data to Redis
// t is the expiration time, in seconds, 0 means no expiration time
func (r *RdbConfig) Set(key string, data interface{}, t time.Duration) error {
	value, err := json.Marshal(data)
	if err != nil {
		return err
	}
	t = t * time.Second
	return r.rDB.Set(context.Background(), key, value, t).Err()
}

func (r *RdbConfig) SetAny(key string, data interface{}, t time.Duration) error {
	t = t * time.Second
	return r.rDB.Set(context.Background(), key, data, t).Err()
}

// Get
// Manipulate String types, read data from Redis
func (r *RdbConfig) Get(key string) (string, error) {
	return r.rDB.Get(context.Background(), key).Result()
}

// HSet
// Manipulate Hash types, read data from Hash structures
func (r *RdbConfig) HSet(key string, id string, data interface{}) error {
	value, err := json.Marshal(data)
	if err != nil {
		return err
	}
	return r.rDB.HSet(context.Background(), key, id, value).Err()
}

// HSetAny
// Manipulate Hash types, write any data to Redis, implements ttl
func (r *RdbConfig) HSetAny(key string, id string, data interface{}, t time.Duration) error {
	t = t * time.Second
	ctx := context.Background()
	err := r.rDB.HSet(ctx, key, id, data).Err()
	if err != nil {
		return err
	}
	return r.rDB.Expire(ctx, key, t).Err()
}

// HGet
// 操作Hash类型, 从Hash结构中读取数据
// key 是Redis查找Hash结构的key
// k   是Hash结构内k-v中的k
func (r *RdbConfig) HGet(key string, k string) (string, error) {
	return r.rDB.HGet(context.Background(), key, k).Result()
}

// HMGet
// 操作Hash类型, 从Hash结构中批量读取数据
// key 是Redis查找Hash结构的key
// k...不定参数 类型string
func (r *RdbConfig) HMGet(key string, k ...string) ([]interface{}, error) {
	return r.rDB.HMGet(context.Background(), key, k...).Result()
}

// HGetAll
// 操作Hash类型, 从Hash结构中读取Key的所有数据
// key 是Redis查找Hash结构的key
func (r *RdbConfig) HGetAll(key string) (map[string]string, error) {
	return r.rDB.HGetAll(context.Background(), key).Result()
}

// HExist
// 操作Hash类型, 判断key存在于Hash结构中
func (r *RdbConfig) HExist(key string, k string) bool {
	exist, err := r.rDB.HExists(context.Background(), key, k).Result()
	if err != nil {
		return false
	}
	return exist
}

// HDelete
// 操作Hash类型, 从Hash结构中删除数据
// key 是Redis查找Hash结构的key
// k   是Hash结构内k-v中的k
func (r *RdbConfig) HDelete(key string, k string) (bool, error) {
	value, err := r.rDB.HDel(context.Background(), key, k).Result()
	return value > 0, err
}

//List 相关操作

// LPush 操作List类型, 将新元素从表头推入List
func (r *RdbConfig) LPush(key string, value interface{}) error {
	return r.rDB.LPush(context.Background(), key, value).Err()
}

// RPush 操作List类型, 将新元素从表尾推入List
func (r *RdbConfig) RPush(key string, value interface{}) error {
	return r.rDB.RPush(context.Background(), key, value).Err()
}

// LLen 操作List类型, 返回List内元素个数
func (r *RdbConfig) LLen(key string) (int64, error) {
	return r.rDB.LLen(context.Background(), key).Result()
}

// LRange 操作List类型, 返回指定范围内元素
func (r *RdbConfig) LRange(key string, start int64, stop int64) ([]string, error) {
	return r.rDB.LRange(context.Background(), key, start, stop).Result()
}

// LRemove 操作List类型, 从表尾向表头搜索移除1个Value
func (r *RdbConfig) LRemove(key string, value interface{}) error {
	return r.rDB.LRem(context.Background(), key, -1, value).Err()
}

//Set 相关操作

// SAdd 操作Set类型, 将数据member写入Set结构中
func (r *RdbConfig) SAdd(key string, member string) error {
	return r.rDB.SAdd(context.Background(), key, member).Err()
}

// SRemove 操作Set类型, 将数据member从Set结构中移除
func (r *RdbConfig) SRemove(key string, member string) error {
	return r.rDB.SRem(context.Background(), key, member).Err()
}

// SIsMember 操作Set类型, 判断member在Set结构中
func (r *RdbConfig) SIsMember(key string, member string) bool {
	isMember, err := r.rDB.SIsMember(context.Background(), key, member).Result()
	if err != nil {
		return false
	}
	return isMember
}

//ZSet 相关操作

// ZAdd 操作ZSet类型, 将Member写入ZSet结构中
func (r *RdbConfig) ZAdd(key string, member interface{}, score float64) error {
	z := redis.Z{
		Score:  score,
		Member: member,
	}
	return r.rDB.ZAdd(context.Background(), key, z).Err()
}

// ZCount 操作ZSet类型, 统计分值在给定范围内节点数量
func (r *RdbConfig) ZCount(key string, min string, max string) (int64, error) {
	return r.rDB.ZCount(context.Background(), key, min, max).Result()
}

// ZRange 操作ZSet类型, 返回给定范围内所有元素
func (r *RdbConfig) ZRange(key string, start int64, stop int64) ([]string, error) {
	return r.rDB.ZRange(context.Background(), key, start, stop).Result()
}

// ZRemove 操作ZSet类型, 删除包含给定成员的所有节点和分值节点
func (r *RdbConfig) ZRemove(key string, member interface{}) error {
	return r.rDB.ZRem(context.Background(), key, member).Err()
}

// Pipeline Pipeline操作
func (r *RdbConfig) Pipeline() redis.Pipeliner {
	return r.rDB.Pipeline()
}
